home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gold Medal Software 5
/
Gold Medal Software - Volume 5 (Gold Medal) (1995).iso
/
utils1
/
cpu_id.arj
/
INTELCPU.TXT
< prev
next >
Wrap
Text File
|
1994-09-20
|
10KB
|
260 lines
The following text has been copied exactly as is from the
_Intel486TM DX Microprocessor Data Book_, including any
and all printing errors. Use at your own risk. I found
a few typos in here while writing my own program!
════════════════════════════════════════════════════════════════════════════
────────────────────────────────────────────────────────────────────────────
Intel486TM DX MICROPROCESSOR
────────────────────────────────────────────────────────────────────────────
APPENDIX A
INTEL RECOMMENDED CPU IDENTIFICATION CODE
The CPU identification assembly code will determine for the user which
Intel microprocessor and if a Intel Math CoProcessor is installed in the
system. If a 486 microprocessor has been installed, the program will
determine if the CPU is with/without a floating point unit. This code
should be executed so the system can be configured for a particular
application, which may depend on the microprocessor and Math CoProcessor
installed in the system.
────────────────────────────────────────────────────────────────────────────
TITLE CPUID
DOSSEG
.model small
.stack 100h
.data
fp_status dw ?
id_mess db "This system has a$"
fp_8087 db "and an 8087 Math CoProcessor$"
fp_80287 db "and an 287tm Math CoProcessor$"
fp_80387 db "and an 387tm Math CoProcessor$"
c8086 db "n8086/8088 microprocessor$"
c286 db "n80286 microprocessor$"
c386 db "386tm microprocessor$"
c486 db "486tm DX microprocessor/487tm SXtm Math
"CoProcessor$"
c486nfp db "486tm SXtm Microprocessor$"
period db ".$",13,10
present_86 dw 0
present_286 dw 0
present_386 dw 0
present_486 dw 0
;
; The purpose of this code is to allow the user the ability to identify
; the processor and coprocesor that is currently in the system. The
; algorithm of the program is to first determine the processor id.
; When that is accomplished, the program continues to then identify
; whether a coprocessor exists in the system. If a coprocessor or
; integrated coprocessor exists, the program will identify the
; coprocessor id. If one does not exist, the program then terminates.
;
.code
start:
mov ax,@data
mov ds,ax ; set segment register
mov dx,offset id_mess ;print header message
mov ah,9h
int 21h
────────────────────────────────────────────────────────────────────────────
A-1
════════════════════════════════════════════════════════════════════════════
Intel486Tm DX MICROPROCESSOR
────────────────────────────────────────────────────────────────────────────
;
; 8086 check
; Bits 12-15 are always set on the 8086 processor.
;
pushf ;save EFLAGS
pop bx ;store EFLAGS in BX
mov ax,0fffh ;clear bits 12-15
and ax,bx ;in EFLAGS
push ax ;store new EFLAGS value on stack
popf ;replace current EFLAGS value
pushf ;set new EFLAGS
pop ax ;store new EFLAGS in AX
and ax,0f000h ;if bits 12-15 are set, then CPU
cmp ax,0f000h ;is an 8086/8088
mov dx,offset c8086 ;store 8086/8088 message
mov present_86,1 ;turn on 8086/8088 flag
je check_fpu ;if CPU is 8086/8088, check for
;8087
;
; 80286 CPU Check
; Bits 12-15 are always clear on the 80286 processor.
;
or bx,0f000h ;try to set bits 12-15
push bx
popf
pushf
pop ax
and ax,0f000h ; if bits 12-15 are cleared, then
mov dx,offset c286 ; CPU is an 80286
mov Present_86,0 ; turn off 8086/8088 flag
mov present_286,1 ; turn on 80286 flag
jz check_fpu ; if CPU is 80286, check for 80287
;
; 386 CPU check
;
; The AC bit, bit #18, is a new bit introduced in the EFLAGS
; on the 486 DX CPU to generate alignment faults. This bit can be set
; on the 486 DX CPU, but not on the 386 CPU.
;
mov bx,sp ;save current stack pointer to
;align it
and sp,not 3 ;align stack to avoid AC fault
db 66h
pushf ;push original EFLAGS
db 66h
pop ax ;get original EFLAGS
db 66h
mov cx,ax ;save original EFLAGS
db 66h ;xor EAX,40000h
xor ax,0 ;flip AC bit in EFLAGS
dw 4 ;upper 16-bits of xor constant
db 66h
push ax ;save for EFLAGS
db 66h
popf ;copy to EFLAGS
────────────────────────────────────────────────────────────────────────────
A-2
════════════════════════════════════════════════════════════════════════════
Intel486Tm DX MICROPROCESSOR
────────────────────────────────────────────────────────────────────────────
db 66h
pushf ;push EFLAGS
db 66h
POP ax ;get new EFLAGS value
db 66h
xor ax,cx ;if AC bit cannot be changed,
;CPU is
mov dx,offset c386 ;store 386 message
mov present_286,0 ;turn off 80286 flag
mov present_386,1 ;turn on 386 flag
Je check_fpu ;if CPU is 386, now check for
;80287/80387
;
; 486 DX CPU and 486 DX CPU w/o FPU checking
;
mov dx,offset c486nfp ;store 486NFP message
mov present_386,0 ;turn off 386 flag
mov present_486,1 ;turn on 486 flag
;
; Co-processor checking begins here for the 8086/80286/386 CPUS.
; The algorithm is to determine whether or not the floating-point
; status and control words can be written to, the correct coprocessor
; is then determined depending on the processor id. Coprocessor checks
; are first performed for an 8086, 80286 and a 486 DX CPU. If the
; coprocessor id is still undetermined, the system must contain a 386
; CPU. The 386 CPU may work with either an 80287 or an 80387. The
; infinity of the coprocessor must be checked to determine the correct
; coprocessor id.
;
check_fpu: ;check for 8087/80287/80387
fninit ; reset FP status word
mov fp_status.5a5ah ;initialize temp word to non-zero
;value
fnstsw fp_status ;save FP status word
mov ax,fp_status ;check FP status word
cmp al,0 ; see if correct status with
; written
jne print_one ;jump if not Valid, no NPX
;installed
fnstcw fp_status ;save FP control word
mov ax,fp_status ;check FP control word
and ax,103fh ;see if selected parts looks OX
cmp ax,3fh ;check that ones and zeroes
;correctly read
jne print_one ;jump if not Valid, no NPX
;installed
cmp present_486,1 ;check if 486 flag is on
je is_486 ;if so, jump to print 486 message
jmp not_486 ;else continue with 386 checking
is_486:
mov dx,offset c486 ;store 486 message
jmp print_one
────────────────────────────────────────────────────────────────────────────
A-3
════════════════════════════════════════════════════════════════════════════
Intel486Tm DX MICROPROCESSOR
────────────────────────────────────────────────────────────────────────────
not_486:
cmp present_386,1 ; check if 386 flag is on
jne print_87_287 ; if 386 flag not on, check NPX for
; 8086/8088/80286
mov ah,9h ; print out 386 CPU ID first
int 21h
;
; 80287/80387 check for the 386 CPU
;
fldl ;must use default control from
;FNINIT
fldz ;form infinity
fdiv ;8087/80287 says +inf = inf
fld st ;form negative infinity
fchs ;80387 says +inf < > -inf
fcompp ;see if they are the same and
;remove them
fstsw fp_status ;look at status from FCOMPP
mov ax,fp_status
mov dx,offset fp_80287 ;store 80287 message
sahf ;see if infinities matched
jz restore_EFLAGS ;jump if 8087/80287 is present
mov dx,offset fp_80387 ;store 80387 message
restore_EFLAGS:
finit ;clear any pending fp exception
mov ah,9h ;print NPX message
int 21h
db 66h
push cx ;push ECX
db 66h
popf ;restore original EFLAGS register
mov sp,bx ;restore original stack pointer
jmp exit
print_one:
mov ah,9h ;print Out CPU ID with no NPX
int 21h
jmp exit
print_87_287:
mov ah,9h ;print out 8086/8088/80286 first
int 21h
cmp present_86,1 ;if 8086/8088 flag is on
mov dx,offset fp_8087 ;store 8087 message
je print_fpu
mov dx,offset fp_80287 ;else CPU = 80286, store 80287
;message
print_fpu:
mov ah,9h ;print out NPX
int 21h
jmp exit
exit:
mov dx,offset period ;print out a period of end message
mov ah,9h
int 21h
mov ax,4c00h ;terminate program
int 21h
end start
────────────────────────────────────────────────────────────────────────────
A-4
════════════════════════════════════════════════════════════════════════════